/*
 * TVisualisation.java
 *
 * Created on 25 wrzesie� 2007, 14:57
 *
 * Klasa s�u�y do tworzenia grafiki
 *
 */

package gra;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.awt.image.BufferedImage; //do eksportu grafiki
import javax.swing.*;
import java.util.ArrayList;
import java.math.BigDecimal;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.behaviors.mouse.*;

/**
 *
 * @author Micha�
 */

public class TVisualisation extends TBarIcon implements MouseBehaviorCallback {
    
    private final static float KAM_X = 0.0f; // pocz�tkowe po�o�enie kamery
    private final static float KAM_Y = 0.0f;
    private final static float KAM_Z = 10.0f;
    
    private final static int INFO_SZER = 150; //szeroko�� panelu informacyjnego
    
    private VirtualUniverse virtualUniverse;
    private BranchGroup branchGroup;
    private Locale locale;
    private TransformGroup transformGroup;
    private GraphicsConfiguration graphicsConfiguration;
    
    private int theSzer, theWys; //rozmiar okna i panelu do wyswietlania
    private int theIle; //ile bedzie wyswietlanych obiektow
    private JTextField theIleTF = new JTextField(); //ile wyswietlanych obiekt�w
    private JTextField theKamPosTF = new JTextField(10); //po�o�enie kamery
    private Canvas3D canvas3D; //potrzebne do eksportu grafiki
    private static File theSrcFile; //plik zrodlowy
    private ArrayList<String[]> fRapAL = new ArrayList<String[]>();
    
    public static void setSrcFile (File aFile) { //ustawienie nazwy pliku
        theSrcFile = aFile;
    } //koniec konstruktora
    
    public TVisualisation()  {
        theIleTF.setPreferredSize(new Dimension(60,20));
        
        //1. Pobieram rozmiar panelu
        theSzer = gra.TBarIcon.screenSize.width;
        theWys = gra.TBarIcon.screenSize.height;
        
        // Utw�rz obiekt virtualUniverse
        virtualUniverse = new VirtualUniverse();
        // Utw�rz obiekt locale o domy�lnym po�o�eniu - (0, 0, 0) - w podanym
        // obiekcie virtualUniverse
        locale = new Locale(virtualUniverse);
        
        // Utw�rz obiekt branchGroup dla modelu bry�y (sze�cianu)
        branchGroup = new BranchGroup();
        // Utw�rz obiekt transformGroup z mo�liwo�ci�  zmiany transformacji
        // na bie��co (w trakcie dzia�ania programu) aby mo�liwa by�a
        // zmiana orientacji sze�cianu
        transformGroup = new TransformGroup();
        transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        // Do��cz obiekt transformGroup do obiektu branchGroup
        branchGroup.addChild(transformGroup);

        // Obs�uga zdarze� za pomoc� myszki
        MouseRotate behRot = new MouseRotate(); //1. Obr�t mysz�
        behRot.setTransformGroup(transformGroup);
        behRot.setupCallback(this); //Dodanie s�uchacza (do oknaInformacyjnego)
        // Do��cz obiekt rotationInterpolator do obiektu branchGroup.
        // Obiekt rotationInterpolator jest zatem po��czony z obiektami klas
        // BranchGroup i TransformGroup (patrz obiekt B na rys. 10.)
        branchGroup.addChild(behRot);
        // Okre�l jaki fragment przestrzeni musi by� widoczny aby uaktywni�
        // obiekt rotationInterpolator (je�eli obiekt nie jest widoczny
        // to nie ma powodu aby obci��a� procesor obliczeniami interpoluj�cymi
        // k�t obrotu sze�cianu). Stworzony wcze�niej sze�cian mie�ci si�
        // w kuli o promieniu 2 
        behRot.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 2.0));
      
        //---
        /*
        //Swiatlo
        /*
        DirectionalLight lig = new DirectionalLight( );
        lig.setEnable(true);
        lig.setColor(new Color3f (1.0f, 1.0f, 1.0f));
        lig.setDirection(new Vector3f( 1.0f, 0.0f, 0.0f));
        BoundingSphere bs = new BoundingSphere(new Point3d( ), 1000.0 );
        lig.setInfluencingBounds(bs);
        branchGroup.addChild(lig);
         */
        //===
        
        //2. Translacja
        MouseTranslate behTra = new MouseTranslate();
        behTra.setTransformGroup(transformGroup);
        behTra.setupCallback(this);
        branchGroup.addChild(behTra);
        behTra.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 2.0));
      
        //3. Zoom
        MouseWheelZoom behZoom = new MouseWheelZoom();
        behZoom.setTransformGroup(transformGroup);
        behZoom.setupCallback(this);
        branchGroup.addChild(behZoom);
        behZoom.setSchedulingBounds(new BoundingSphere(new Point3d(0.0,0.0,0.0), 2.0));
        
        //obs�uga zamkni�cia okna
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter(){
            public void windowClosing (WindowEvent e) {
                //virtualUniverse.removeAllLocales();
                virtualUniverse = null;
                branchGroup = null;
                locale = null;
                transformGroup = null;
                dispose();
            } //koniec wC
        });
        //=== koniec obs�ugi myszy
        
        //4. Og�lne dane do okna
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(getInfoP(), BorderLayout.EAST);
    } //koniec konstruktora
    
    public void display() { //dalsza czesc� konstruktora.
        prepareTF(theIleTF, String.valueOf(theIle)); //przygotowuje JTextField
        
        // Kompiluj zdefiniowany fragment sceny aby przyspieszy� p�niejszy rendering
        branchGroup.compile();
        // Sze�cian jest gotowy - dodaj obiekt branchGroup zawieraj�cy jego 
        // opis do obiektu locale
        locale.addBranchGraph(branchGroup);
            
        /************* Sekcja obs�ugi kamery *****************/
        // Utw�rz nowy obiekt klasy BranchGroup - dla kamery
        BranchGroup branchGroupKamera = new BranchGroup();
        // Utw�rz nowy obiekt klasy TransformGroup
        TransformGroup transformGroupKamera = new TransformGroup();
        // Do��cz obiekt transformGroup do obiektu branchGroup
        branchGroupKamera.addChild(transformGroupKamera);
        // Utw�rz obiekt viewPlatform
        ViewPlatform viewPlatform = new ViewPlatform();
        // Do��cz obiekt viewPlatform do obiektu transformGroup
        transformGroupKamera.addChild(viewPlatform);
        // Utw�rz obiekt view
        View view = new View();
        // Do��cz obiekt physicalBody z domy�lnymi ustawieniami
        view.setPhysicalBody(new PhysicalBody());
        // Do��cz obiekt physicalEnvironment z domy�lnymi ustawieniami
        view.setPhysicalEnvironment(new PhysicalEnvironment());
        // Do��cz obiekt viewPlatform do obiektu view
        view.attachViewPlatform(viewPlatform);
        //=== koniec sekcji obs�ugi kamery
           
        // Pobierz wz�r konfiguracji �rodowiska 
        // graficznego kompatybilny z Java3D
        GraphicsConfigTemplate3D graphicsConfigTemplate3D = 
                                            new GraphicsConfigTemplate3D();
        // Pobierz list� urz�dze� graficznych dost�pnych lokalnie
        // (tzn. znajduj�cych si� na komputerze, na kt�rym wykonywany jest applet),
        // spo�r�d nich wybierz domy�lne urz�dzenie ekranowe (a nie np. drukark�)
        // i zwr�� najlepsz� konfiguracj� znalezionego urz�dzenia kt�re spe�nia
        // kryteria okre�lone przez obiekt graphicsConfigTemplate3D
        GraphicsConfiguration graphicsConfiguration = GraphicsEnvironment
                        .getLocalGraphicsEnvironment()
                        .getDefaultScreenDevice()
                        .getBestConfiguration(graphicsConfigTemplate3D);
        
        // Utw�rz i skonfiguruj komponent 
        //Canvas3D canvas3D = new Canvas3D(graphicsConfiguration);
        if (graphicsConfiguration == null) return; //dla czego to sie dzieje?
        canvas3D = new Canvas3D(graphicsConfiguration);
        // Okre�l wymiary komponentu canvas3D
        
        canvas3D.setBounds(0, 0, theSzer-INFO_SZER, theWys);
        // Umie�� komponent Canvas3D na panelu appletu
        getContentPane().add(canvas3D, BorderLayout.CENTER);

        // Dodaj obiekt canvas3D do obiektu view
        view.addCanvas3D(canvas3D);
        // Utw�rz obiekt transform3D (zawiera on wewn�trz macierz transformacji)
        Transform3D transform3D = new Transform3D();
        // Cofnij kamer� (dokonaj translacji) (o� Z skierowana jest w kierunku kamery)
        transform3D.set(new Vector3d(KAM_X, KAM_Y, KAM_Z)); //widok z g�ry !!!!!
        
        // Przypisz macierz transformacji do obiektu transformGroup
        transformGroupKamera.setTransform(transform3D);

        // Kamera jest gotowa - dodaj obiekt branchGroup zawieraj�cy jej opis do
        // obiektu locale
        locale.addBranchGraph(branchGroupKamera);
        setSize(theSzer,theWys);
        setVisible(true);
    } //koniec display
   
    //public void addData(Point3d[] pts, String aStr) { //dodanie danych (pkt�w)
    public void addPtT(Point3d[] pts) { //dodanie danych (pktow)
        String _title = "";
        if (theSrcFile != null) _title = theSrcFile.getAbsolutePath().concat(" - ");
        setTitle(_title.concat("PUNKTY"));
        theIle += pts.length; //licznik wy�wietlanych obiekt�w

        PointArray pa = new PointArray(pts.length, PointArray.COORDINATES);
        pa.setCoordinates(0, pts);
        transformGroup.addChild(new Shape3D(pa));
    } //koniec addPtT
    
    public void addLineT(Point3d[] pts) {
        setTitle(theSrcFile.getAbsolutePath().concat(" - ODCINKI"));
         
        //theIle += pts.length; //licznik wy�wietlanych obiekt�w
        //prepareTF(theIleTF, String.valueOf(pts.length)); //przygotowuje JTextField
//
        // linie
        LineArray la = new LineArray(pts.length, PointArray.COORDINATES);
        la.setCoordinates(0, pts);
        transformGroup.addChild(new Shape3D(la));
//System.out.println ("ccc addLineT theIle: " + theIle + ", pts.l: " + pts.length);
//for (int i=0; i<pts.length; i++)
//    System.out.println ("pts[" + i + "]: " + pts[i]);
        theIle += pts.length/2;
//System.out.println ("ddd addPtT theIle: " + theIle);
    } //koniec addLineT
    
    public void addPlaneT(Point3d[] pts) {
//System.out.println ("pts.l: " + pts.length);
        QuadArray qa = new QuadArray(pts.length, GeometryArray.COORDINATES);// | GeometryArray.COLOR_3);
        for (int i=0; i<pts.length; i++)    qa.setCoordinate(i, pts[i]);
        transformGroup.addChild(new Shape3D(qa, createApp()));
//System.out.println ("eee addPlaneT theIle: " + theIle);
        theIle += pts.length/4;
//System.out.println ("fff addPlaneT theIle: " + theIle);
    } //koniec addPlaneT

    //---
    public void triTest() { //pr�ba narysowania tr�jk�ta w jakim� kolorze
        Point3f[] myCoords = {
            new Point3f( 0.0f, 0.0f, 0.0f ),
            new Point3f( 0.0f, 1.0f, 0.0f ),
            new Point3f( 0.0f, 1.0f, 1.0f ),
        };
        /*
        Vector3f[] myNormals = { //co to jest?
            new Vector3f( 0.0f, 1.0f, 0.0f ),
            new Vector3f( 0.0f, 1.0f, 1.0f ),
            new Vector3f( 0.0f, 0.0f, 0.0f ),
        };
         */

        Vector3f[] myNormals = { //co to jest?
            new Vector3f( 1.0f, 0.0f, 0.0f ),
            new Vector3f( 0.0f, 1.0f, 0.0f ),
            new Vector3f( 0.0f, 0.0f, 1.0f ),
        };

        TriangleArray myTris = new TriangleArray(
                                        myCoords.length,
                                        GeometryArray.COORDINATES |
                                        GeometryArray.NORMALS);
         /*
        TriangleArray myTris = new TriangleArray(
                                        myCoords.length,
                                        GeometryArray.COORDINATES);
          */
        myTris.setCoordinates( 0, myCoords );
        myTris.setNormals( 0, myNormals );
        
        //Kolor
        /*
        ColoringAttributes myCA = new ColoringAttributes( );
        Color graphColor = new Color(46, 139, 87);
        myCA.setColor(new Color3f(graphColor));
        //myCA.setColor( 0.0f, 1.0f, 0.0f );
        myCA.setShadeModel( ColoringAttributes.SHADE_GOURAUD );
        */
        
        //Materia�
        Material myMat = new Material( );
        myMat.setAmbientColor( 0.3f, 0.3f, 0.3f );
        myMat.setDiffuseColor( 0.0f, 0.0f, 1.0f );
        myMat.setEmissiveColor( 0.0f, 1.0f, 0.0f ); //zmieni�, bo na czarnym nie widac
        myMat.setSpecularColor( 1.0f, 1.0f, 1.0f );
        myMat.setShininess( 64.0f );

        /*
        Material myMat = new Material( );
        myMat.setAmbientColor( 0.3f, 0.3f, 0.3f );
        myMat.setDiffuseColor( 1.0f, 0.0f, 0.0f );
        myMat.setEmissiveColor( 0.0f, 0.0f, 0.0f ); //zmieni�, bo na czarnym nie widac
        myMat.setSpecularColor( 1.0f, 1.0f, 1.0f );
        myMat.setShininess( 64.0f );
        */        
        
        PolygonAttributes myPA = new PolygonAttributes( );
        myPA.setCullFace( PolygonAttributes.CULL_NONE );
        myPA.setPolygonMode( PolygonAttributes.POLYGON_FILL );
        
        Appearance myAppear = new Appearance( );
        //myAppear.setColoringAttributes( myCA );
        myAppear.setMaterial(myMat);
        myAppear.setPolygonAttributes(myPA);

        //myAppear.setMaterial(myMat);
        Shape3D myShape = new Shape3D( myTris, myAppear);
        transformGroup.addChild(myShape);
    } //koniec triTest
    
    public void addTriangleT(Point3d[] pts) {
        Color _col = Color.GREEN;//new Color(46, 139, 87); //ladny ciemnozielony
        this.addTriangleT(pts, _col);
    } //koniec addTriangleT

    /*
    public void addTriangleT(Point3d[] pts, Color aCol) {
        //TriangleArray ta = new TriangleArray(pts.length, GeometryArray.COORDINATES);
        TriangleArray ta = new TriangleArray(pts.length, 
                            GeometryArray.COORDINATES | GeometryArray.NORMALS);
        Vector3f[] _nor = { //co to jest?
            new Vector3f( 1.0f, 1.0f, 1.0f ),
            new Vector3f( 1.0f, 1.0f, 1.0f ),
            new Vector3f( 0.0f, 0.0f, 0.0f ),
        };

        //for (int i=0; i<pts.length; i++)    ta.setCoordinate(i, pts[i]);
        ta.setCoordinates(0, pts);
        ta.setNormals(0, _nor);

        //Materia�
        Material mat = new Material( );
        mat.setAmbientColor( 0.3f, 0.3f, 0.3f );
        mat.setDiffuseColor( 0.0f, 1.0f, 0.0f );
        mat.setEmissiveColor( 0.0f, 1.0f, 0.0f ); //zmieni�, bo na czarnym nie widac
        mat.setSpecularColor( 1.0f, 1.0f, 1.0f );
        mat.setShininess( 64.0f );
        
        //--
        PolygonAttributes pa = new PolygonAttributes( );
        pa.setCullFace (PolygonAttributes.CULL_NONE);
        pa.setPolygonMode (PolygonAttributes.POLYGON_FILL);
        
        Appearance appear = new Appearance( );
        appear.setMaterial(mat);
        appear.setPolygonAttributes(pa);

        Shape3D s3D = new Shape3D(ta, appear);
        transformGroup.addChild(s3D);
        //==
        
        //transformGroup.addChild(new Shape3D(ta, createApp(aCol)));
        theIle += pts.length/3;
    } //koniec addPlaneT
*/

    public void addTriangleT(Point3d[] pts, Color aCol) {
        TriangleArray ta = new TriangleArray(pts.length, GeometryArray.COORDINATES);
        for (int i=0; i<pts.length; i++)    ta.setCoordinate(i, pts[i]);
        transformGroup.addChild(new Shape3D(ta, createApp(aCol)));
        theIle += pts.length/3;

        //---
        /*
        //Dodaje ramke trojkata
        /*
        for (int i=0; i<pts.length; i++) {
            Point3d[] p3d = new Point3d[2]; //bo odcinek
            p3d[0] = pts[i];
            p3d[1] = (i==pts.length-1 ? pts[0] : pts[i+1]);
            
            LineArray la = new LineArray(p3d.length, PointArray.COORDINATES);
            la.setCoordinates(0, p3d);

            //Kolor
            ColoringAttributes myCA = new ColoringAttributes( );
            Color graphColor = Color.RED;//new Color(46, 139, 87);
            myCA.setColor(new Color3f(graphColor));
            //myCA.setColor( 0.0f, 1.0f, 0.0f );
            myCA.setShadeModel( ColoringAttributes.SHADE_GOURAUD );

            Appearance myAppear = new Appearance( );
            myAppear.setColoringAttributes( myCA );

            //myAppear.setMaterial(myMat);
            Shape3D myShape = new Shape3D (la, myAppear);
            transformGroup.addChild(myShape);
        } //koniec for
         */ 
        //===
    } //koniec addTriangleT

    private Appearance createApp() {  //zeby malowal plaszczyzny z dwoch stron
        return createApp(Color.WHITE);
    }
    
    private Appearance createApp(Color aCol) {  //zeby malowal plaszczyzny z dwoch stron
        Appearance app=new Appearance(); 
        //1. Rysowanie plaszczyzn z dwoch stron
        PolygonAttributes polyAttrib = new PolygonAttributes(); 
        polyAttrib.setCullFace(PolygonAttributes.POLYGON_POINT); 
        app.setPolygonAttributes(polyAttrib); 
        
        //2. Kolorowanie
        ColoringAttributes colAttr = new ColoringAttributes( );
        colAttr.setColor((float)aCol.getRed()/255f, (float)aCol.getGreen()/255f, (float)aCol.getBlue()/255f);
        colAttr.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
        app.setColoringAttributes(colAttr);
        
        return app; 
    } //koniec createApp

    /*
    private Appearance createApp() {  //�eby malowa� p�aszczyzny z dw�ch stron
        Appearance app=new Appearance(); 
        PolygonAttributes polyAttrib = new PolygonAttributes(); 
        polyAttrib.setCullFace(PolygonAttributes.POLYGON_POINT); 
        //app.setCapability (Appearance.ALLOW_COLORING_ATTRIBUTES_WRITE); 

        //app.setColoringAttributes (new ColoringAttributes (new Color3f (0.0f, 0.0f, 1.0f),1)); 
        //Color3f objColor = new Color3f(0.5f, 0.5f, 0.6f); 
        //Color3f black = new Color3f(0.0f, 0.0f, 0.0f); 
        //Color3f white = new Color3f(1.0f, 1.0f, 1.0f); 
        //app.setMaterial(new Material(objColor, black, objColor, white, 10.0f)); 
        //ColoringAttributes ca = new ColoringAttributes(); 
        //ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD); 
        //app.setColoringAttributes(ca); 
        app.setPolygonAttributes(polyAttrib); 
        return app; 
    } //koniec createApp

     */    
    //Panel informacyjny
    private JComponent getInfoP() {
        JPanel jp = new JPanel();
        jp.setPreferredSize(new Dimension(INFO_SZER, theWys));
        String[] lDesc = {"Informacje", "Ile obiektow", "Polozenie kamery", 
                    "Zdjecie"};
        int _cnt = 0; //licznik pomocniczy
        
        //1. Naglowek
        JLabel nagL = new JLabel(lDesc[_cnt++]);
        nagL.setFont(new Font("System", Font.BOLD, 15));
        jp.add(nagL);
        jp.add(new JSeparator());
        
        //2. Ile obiektow
        jp.add(new JLabel(lDesc[_cnt++].concat(": ")));
        jp.add(theIleTF);
        
        //3. Punkt kamery
        jp.add(new JLabel(lDesc[_cnt++].concat(": ")));
        StringBuffer _sb = new StringBuffer().append(round(KAM_X)).append(", ").
                append(round(KAM_Y)).append(", ").append(round(KAM_Z));
        prepareTF(theKamPosTF, _sb.toString());
        jp.add(theKamPosTF);
        
        //... Dorobi� k�ty obrotu kamery
        
        //4. Przycisk do zdj�cia
        JButton zdjB = new JButton(lDesc[_cnt++]);
        zdjB.addActionListener(new ActionListener(){
            public void actionPerformed (ActionEvent e) { exportGra(); }
        });
        jp.add(zdjB);
        
        return jp;
    } //koniec getInfoP
    
    //Metoda z interfejsu
    public void transformChanged(int type, Transform3D transform) {
        //1. Pobieram przesuni�cie i obliczam po�o�enie kamery
        Vector3f v3 = new Vector3f(); //pozycja pocz�tkowa
        transform.get(v3);
        StringBuffer _sb = new StringBuffer().append(round(KAM_X-v3.x)).append(", ").
                append(round(KAM_Y-v3.y)).append(", ").append(round(KAM_Z-v3.z));
        theKamPosTF.setText(_sb.toString());
        
        //.... pobra� obr�t kamery
        /*
        float[] posT = new float[16];
        transform.get(posT);
        System.out.println ("v3: " + v3);
        for (int i=0; i<posT.length; i++)
            System.out.println ("posT[" + i + "]: " + posT[i]);
        */
    }//koniec transformChanged
    
    //Metody pomocnicze
    private void prepareTF(JTextField aTF, String aText) {
        aTF.setFont(theKamPosTF.getFont().deriveFont(Font.BOLD));
        aTF.setMargin(new Insets(1,3,1,3)); //marginesy
        aTF.setHorizontalAlignment(JTextField.CENTER);
        aTF.setEditable(false);
        aTF.setText(aText);
    } //koniec prepareTF
    
    private static float round(double aVal) {
        BigDecimal bD = new BigDecimal(aVal);
        return bD.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
    } //koniec round

    private void exportGra() //eksportuje aktywn� graifk� np do jpeg
    {
        String pngExt = ".png";//do eksportu aktywnej grafiki
        String jpgExt = ".jpg";//do eksportu aktywnej grafiki
        
        BufferedImage obraz = new BufferedImage(canvas3D.getWidth(), 
                                canvas3D.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2D = (Graphics2D)obraz.getGraphics();
        canvas3D.print(g2D);
   
        //Okno do wyboru pliku
        FileDialog fds = new FileDialog(this,
                "Zapisz aktywny obraz jako (jpg lub png)...", FileDialog.SAVE);
        //fds.setDirectory(System.getProperty("user.dir"));

        String _fileName = theSrcFile.getName();
        if (_fileName.indexOf('.') != -1)  //obcinam z nazwy rozszerzenie
            _fileName = _fileName.substring(0, _fileName.indexOf('.'));
        fds.setDirectory(theSrcFile.getParent());
        String PT = "pt"; //poprawi� po zrobieniu.
        fds.setFile(_fileName.concat("_").concat(PT).concat(pngExt));
        fds.setVisible (true);
        String _eksFilN = fds.getFile();
        String _eksDirN = fds.getDirectory();

        if (_eksFilN != null) {//czyli wybrano jaki� plik + zapisz a nie Anuluj
            //Ewentualne dopisanie rozszerzenia, je�eli u�ytkownik tego nie zrobi�
            if (!_eksFilN.endsWith(jpgExt) && !_eksFilN.endsWith(pngExt))
                _eksFilN = _eksFilN.concat(pngExt);
            try {
                javax.imageio.ImageIO.write(obraz, 
                        _eksFilN.endsWith(pngExt) ? "png" : "jpg", 
                        new File(_eksDirN + _eksFilN));
                //Tworz� plik z raportem
                String _rapFilN = _eksFilN;
                if (_rapFilN.indexOf('.') != -1)  //usuwam rozszerzenie
                    _rapFilN = _rapFilN.substring(0, _rapFilN.indexOf('.'));
                _rapFilN = _rapFilN.concat(".txt");
                File _rapFile = new File(_eksDirN +_rapFilN);
                try {
                    PrintWriter pw = new PrintWriter (
                                        new BufferedWriter(
                                            new FileWriter(_rapFile, false)));
                    String[] lDesc = {
                        "Nazwa pliku graficznego",
                        "Ilo�� obiekt�w",
                        "Po�o�enie kamery",
                        "Ustawienie kamery"
                    };
                    int _cnt = 0; //licznik pomocniczy
                    
                    //Tworz� raport
                    pw.println(lDesc[_cnt++].concat(" :\t").concat(_eksFilN));
                    pw.println(lDesc[_cnt++].concat(" :\t").concat(theIleTF.getText()));
                    pw.println(lDesc[_cnt++].concat(" :\t").concat(theKamPosTF.getText()));
                    pw.println(lDesc[_cnt++].concat(" :\t").concat("???"));
                    
                    for (String[] rapStr : fRapAL) {
                        if (rapStr.length==2) { //czyli ok
                            pw.println(rapStr[0].concat(" :\t").concat(rapStr[1]));        
                        } //koniec if
                    } //koniec for
                    
                    pw.flush();
                    pw.close();
                } catch (IOException err) {
                    System.err.println ("ERR_03: " + err);
                } //koniec try-catch

                //.....
                
            } catch (IOException err) {
                JOptionPane.showMessageDialog(this, 
                        "Nie uda�o si� wyeksportowa� aktywnej grafiki !",
                        "Zapis do pliku", JOptionPane.ERROR_MESSAGE);
            } //koniec try-catch
        } //koniec if (_eksFilN != null)
    } //koniec exportGra
    
    public void addMes (String aDesc, String aVal) { //dodaje opis do raportu
        String[] _str = {aDesc, aVal};
        fRapAL.add(_str);
    } //koniec addMes
} //koniec klasy TVisualisation
